package Thread;

/**
 * 单例模式的实现(懒汉模式)
 */

//推迟创建实例的时机到第一次使用的时候

//懒汉模式的创建
class SingletonLazy{
    //此处先把这个实例的引用设置为null,先不着急创建实例

    //这个地方要加上volatile防止发生内存可见性问题
    private static volatile SingletonLazy instance = null;

    //创建一个锁对象
    private static Object locker = new Object();

    public static SingletonLazy getInstance(){
        //在这个条件中判定当前是否应该要加锁
        if (instance == null){
            //在没有加锁的情况下，检查 instance 是否为 null。
            // 如果为 null，表示还没有创建单例实例，此时进入加锁代码块。
            synchronized (locker){
                //使用 synchronized 关键字确保只有一个线程能够进入该代码块，
                // 保证线程安全。此时，即使多个线程进入 getInstance 方法，它们也不会同时创建多个实例。
                if(instance == null){
                    //在加锁之后，必须再次检查 instance 是否为 null，
                    // 这是因为其他线程可能已经在前一个检查之后创建了实例。
                    // 如果不进行第二次检查，可能会导致多个线程创建多个实例。
                    instance = new SingletonLazy();
                }
            }
        }
        return instance;
    }

    //将类的构造方法设置为私有方法,防止再次创建类的实例
    private SingletonLazy(){}
}

public class Demo29 {
    public static void main(String[] args) {
        SingletonLazy s1 = SingletonLazy.getInstance();
        SingletonLazy s2 = SingletonLazy.getInstance();

        System.out.println(s1 == s2);
    }
}
